package moniter

import (
	"fmt"
	"strings"
	"sync"
	"time"
)

var lock sync.Mutex
var moniter_once sync.Once

var timeInterval int //时间间隔 秒

type Info struct {
	Name        string //协议名
	Req         int32  //请求数量
	Resp        int32
	TotalTime   int64
	MaxTime     int64
	AverageTime float64
	Count       int64
}

var NameRespTime map[string]int64
var NameToInfo map[string]*Info

func Register(name string) {
	if _, ok := NameToInfo[name]; !ok {
		NameToInfo[name] = &Info{
			Name:        name,
			Req:         0,
			Resp:        0,
			TotalTime:   0,
			MaxTime:     0,
			AverageTime: 0,
			Count:       0,
		}

		fmt.Println("Register", name)
	}
}

func (this *Info) ClearInfo() {
	defer lock.Unlock()
	lock.Lock()

	this.Req = 0
	this.Resp = 0
	this.TotalTime = 0
	this.MaxTime = 0
	this.AverageTime = 0
	this.Count = 0
}

func ReportInfo(ns, method string, tt string) {
	defer lock.Unlock()
	lock.Lock()

	repTime := time.Now().UnixNano() / 1e6
	name := ""

	if ns == "SC" {
		s := strings.Split(method, ".")
		name = s[1]
	} else if ns == "SS" {
		s := strings.Split(method, ".")
		name = s[1]
	} else if ns == "RPC" {
		s := strings.Split(method, ".")
		name = s[1]
	}

	info := NameToInfo[name]
	if info == nil {
		return
	}

	if tt == "req" {
		NameRespTime[name] = repTime
		info.Req++
	} else if tt == "resp" {
		info.Resp++
		if NameRespTime[name] != 0 {
			respTime := repTime - NameRespTime[name]
			if info.MaxTime == 0 || respTime > info.MaxTime {
				info.MaxTime = respTime
			}

			info.TotalTime += respTime
			info.Count++
			info.AverageTime = float64(info.TotalTime) / float64(info.Count)

			NameRespTime[name] = 0
		}
	}
}

func Tick() {
	for {
		ReportToHttp()
		for _, info := range NameToInfo {
			info.ClearInfo()
		}
		time.Sleep(time.Second * time.Duration(timeInterval))
	}
}

func Init() {
	moniter_once.Do(func() {
		timeInterval = 1
		NameToInfo = map[string]*Info{}
		NameRespTime = map[string]int64{}

		InitRegister()

		go Tick()

		localAddr := "10.128.2.153:10002"
		remoteAddr := "10.128.2.153:10001"
		go HttpStart(localAddr, remoteAddr)
	})
}
